home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / a_utils / yacc / occam.lha / occam / occam2lex.c < prev    next >
C/C++ Source or Header  |  1989-08-22  |  9KB  |  477 lines

  1. /*
  2.  *    OCCAM2 lexical analysis routine
  3.  *
  4.  *    pjmp    HRC    9/3/89
  5.  *
  6.  */
  7.  
  8. /*
  9.  * This work is in the public domain.
  10.  * It was written by Peter Polkinghorne in 1986 & 1989 at
  11.  * GEC Hirst Research Centre, Wembley, England.
  12.  * No liability is accepted or warranty given by the Author,
  13.  * still less my employers.
  14.  */
  15.  
  16. /* revision history
  17.  
  18.     0.0    first release                    pjmp    9/3/89
  19.  
  20. end revisions */
  21.  
  22. #include <stdio.h>
  23. #include <ctype.h>
  24. #include "lex2.h"
  25.  
  26. #define    MAXLINE    256
  27.  
  28. #define    TRUE    1
  29. #define    FALSE    0
  30.  
  31. /************************************************************************/
  32. /* reserved word list - ordered for binary chomp */
  33.  
  34. static struct reserv { char * word; int tok, len; } rlist[] = {
  35.         "AFTER",    AFTER,    5,
  36.         "ALT",        ALT,    3,
  37.         "AND",        BOOLOP,    3,
  38.         "ANY",        ANY,    3,
  39.         "AT",        AT,    2,
  40.         "BYTE",        BYTE,    4,
  41.         "CASE",        CASE,    4,
  42.         "CHAN",        CHAN,    4,
  43.         "DEF",        DEF,    3,
  44.         "ELSE",        ELSE,    4,
  45.         "FALSE",    BOOL,    5,
  46.         "FOR",        FOR,    3,
  47.         "FROM",        FROM,    4,
  48.         "FUNCTION",    FUNCTION,    8,
  49.         "IF",        IF,    2,
  50.         "INT",        INT,    3,
  51.         "INT16",    INT16,    5,
  52.         "INT32",    INT32,    5,
  53.         "INT64",    INT64,    5,
  54.         "IS",        IS,    2,
  55.         "MOSTNEG",    MOSTNEG,7,
  56.         "MOSTPOS",    MOSTPOS,7,
  57.         "NOT",        NOT,    3,
  58.         "NOW",        NOW,    3,
  59.         "OR",        BOOLOP,    2,
  60.         "OF",        OF,    2,
  61.         "PAR",        PAR,    3,
  62.         "PLACE",    PLACE,    5,
  63.         "PLACED",    PLACED,    6,
  64.         "PORT",        PORT,    4,
  65.         "PRI",        PRI,    3,
  66.         "PROC",        PROC,    4,
  67.         "PROCESSOR",    PROCESSOR,    9,
  68.         "PROTOCOL",    PROTOCOL,    8,
  69.         "ROUND",    ROUND,    5,
  70.         "REAL",        REAL,    4,
  71.         "REAL32",    REAL32,    6,
  72.         "REAL64",    REAL64,    6,
  73.         "RESULT",    RESULT,    6,
  74.         "RETYPES",    RETYPES,    7,
  75.         "SEQ",        SEQ,    3,
  76.         "SIZE",        SIZE,    4,
  77.         "SKIP",        SKIP,    4,
  78.         "STOP",        STOP,    4,
  79.         "TABLE",    TABLE,    5,
  80.         "TIMER",    TIMER,    5,
  81.         "TO",        TO,    2,
  82.         "TRUE",        BOOL,    4,
  83.         "TRUNC",    TRUNC,    5,
  84.         "VALUE",    VALUE,    5,
  85.         "VAL",        VAL,    3,
  86.         "VALOF",    VALOF,    5,
  87.         "VAR",        VAR,    3,
  88.         "WHILE",    WHILE,    5,
  89.         0,        0,    0
  90.  
  91.     };
  92.  
  93. /************************************************************************/
  94.  
  95. static    char    line[MAXLINE];    /* where we store the input, line as a time */
  96.  
  97. char    yytext[MAXLINE];    /* where we store text associated with token */
  98.  
  99. int    yylineno=1,        /* line number of input */
  100.     yylen;            /* amount of text stored */
  101.  
  102. static    int    llen,        /* how much in line */
  103.         curind,        /* current indentation */
  104.         indent=0;    /* this lines indent */
  105.         ldebug = TRUE,    /* set to TRUE for debug */
  106.         index;        /* where we are in the line */
  107.  
  108. /* state we are in: either start - get new input, decide what next
  109.             ind - processing indentation
  110.             rest - processing some occam stmt
  111.             eof - tidy up processing
  112. */
  113.  
  114. static    enum    lexstate { Start, Ind, Rest, Eof } state = Start;
  115.  
  116. /************************************************************************/
  117.  
  118. yylex()
  119. /* this function returns the next token (defined by lex.h), a character
  120. value or 0 for end of input. The tokens are defined by standard input
  121. */
  122. {
  123.     int    tok = -1,    /* token to return - init to impossible value */
  124.         sind = index;    /* start of input being processed */
  125.  
  126. /* go round and round until token to return */
  127.     while ( tok < 0  ) {
  128.  
  129. /* decide by state */
  130.     switch (state) {
  131.  
  132.         case Start: {
  133. /*grab some more line */
  134.             if ( fgets( line, MAXLINE-1, stdin ) == NULL ) {
  135.                 state = Eof;
  136.                 break;
  137.  
  138.             } else if ( (llen=strlen(line)) >= MAXLINE-1 ) {
  139.                 fprintf( stderr,
  140.                     "line <%s> longer than %d\n",
  141.                     line, MAXLINE-1 );
  142.                 exit( 1 );
  143.             }/*if*/
  144.  
  145.             index = 0;
  146.             sind = 0;
  147.             indent = 0;
  148.  
  149.  
  150. /* if blank line OR has just comment skip, otherwise got to appropriate state */
  151.  
  152.             if ( m_nulline() ) {
  153.                 /* do nowt */
  154.  
  155.             } else if ( line[0]==' ' && line[1]==' ' ) {
  156.                 state = Ind;
  157.  
  158.             } else {
  159.                 state = Rest;
  160.  
  161.             }/*if*/
  162.  
  163.         break;}/*Start*/
  164.  
  165.         case Ind: {
  166. /* work out indentation */
  167.             if ( line[index]==' ' && line[index+1]==' ' ) {
  168.                 indent++;
  169.                 index+=2;
  170.                 sind+=2;
  171.             } else {
  172.                 state = Rest;
  173.             
  174.             }/*if*/
  175.     
  176.         break;}/*Ind*/
  177.  
  178.         case Rest: {
  179. /* do we have some indentation to adjust for ... */
  180.             if ( curind > indent ) {
  181.                 curind--;
  182.                 tok = END;
  183.                 break;
  184.  
  185.             } else if ( curind < indent ) {
  186.                 curind++;
  187.                 tok = BEG;
  188.                 break;
  189.  
  190.             }/*if*/
  191.  
  192. /* process ch as appropriate */
  193.             switch ( line[index] ) {
  194.  
  195. /* space ignored */
  196.                 case ' ': {
  197.                     sind++;
  198.                     index++;
  199.                 break;}
  200.  
  201. /* eol change state again */
  202.                 case '\n': {
  203.                     yylineno++;
  204.                     index++;
  205.                     state = Start;
  206.                     tok = EOL;
  207.                 break;}
  208.  
  209. /* - a comment perhaps OR just itself */
  210.                 case '-': {
  211.                     if ( line[index+1] == '-' ) {
  212.                         index = llen+1;
  213.                         state = Start;
  214.                         tok = EOL;
  215.  
  216.                     } else {
  217.                         tok = line[index++];
  218.  
  219.                     }/*if*/
  220.                 break;}
  221.  
  222.                 case '<': {
  223.                     if ( line[index+1] == '<' ) {
  224.                         index+=2;
  225.                         tok = SHIFTOP;
  226.  
  227.                     } else {
  228.                         if ( line[index+1] == '=' ||
  229.                             line[index+1] == '>' ) {
  230.                             index++;
  231.                         }/*if*/
  232.                         index++;
  233.                         tok = COMPOP;
  234.                     }/*if*/
  235.                 break;}
  236.  
  237.                 case '>': {
  238.                     if ( line[index+1] == '>' ) {
  239.                         index+=2;
  240.                         tok = SHIFTOP;
  241.  
  242.                     } else if ( line[index+1] == '<' ) {
  243.                         index+=2;
  244.                         tok = LOGOP;
  245.  
  246.                     } else {
  247.                         if ( line[index+1] == '=' ) {
  248.                             index++;
  249.                         }/*if*/
  250.                         index++;
  251.                         tok = COMPOP;
  252.                     }/*if*/
  253.  
  254.                 break;}
  255.  
  256.                 case '/': {
  257.                     if ( line[index+1] == '\\' ) {
  258.                         index+=2;
  259.                         tok = LOGOP;
  260.  
  261.                     } else {
  262.                         tok = line[index++];
  263.  
  264.                     }/*if*/
  265.                 break;}
  266.  
  267.                 case '\\': {
  268.                     if ( line[index+1] == '/' ) {
  269.                         index+=2;
  270.                         tok = LOGOP;
  271.  
  272.                     } else {
  273.                         tok = line[index++];
  274.  
  275.                     }/*if*/
  276.                 break;}
  277.  
  278.                 case '#': {
  279.                     if ( isxdigit( line[index+1] ) ) {
  280. /* gobble up hex digits */
  281.                         index++;
  282.                         while ( isxdigit(line[index]) ){
  283.                             index++;
  284.                         }/*while*/
  285.  
  286.                         tok = NUMBER;
  287.  
  288.                     } else {
  289.                         tok = line[index++];
  290.  
  291.                     }/*if*/
  292.  
  293.                 break;}
  294.  
  295.                 case '\'': {
  296.                     if ( line[index+1] != '*'
  297.                          && line[index+2] == '\'' ) {
  298.  
  299.                         index+=3;
  300.                         tok = CHCON;
  301.  
  302.                     } else if ( line[index+1] == '*'
  303.                          && line[index+2] != '#' 
  304.                          && line[index+3] == '\'' ) {
  305.  
  306.                         index+=4;
  307.                         tok = CHCON;
  308.  
  309.                     } else if ( line[index+1] == '*'
  310.                          && line[index+2] == '#' 
  311.                          && isxdigit( line[index+3] )
  312.                          && isxdigit( line[index+4] )
  313.                          && line[index+5] == '\'' ) {
  314.  
  315.                         index+=6;
  316.                         tok = CHCON;
  317.  
  318.                     } else {
  319.                         tok = line[index++];
  320.  
  321.                     }/*if*/
  322.  
  323.                 break;}
  324.  
  325.  
  326.                 case '"': {
  327.                     int    lindex=index+1;
  328.  
  329.                     while ( line[lindex] != '"'
  330.                          && lindex <= llen ) {
  331.                         lindex++;
  332.                     }/*while*/
  333.  
  334.                     if ( line[lindex] == '"' ) {
  335.                         index = lindex+1;
  336.                         tok = STR;
  337.  
  338.                     } else {
  339.                         tok = line[index++];
  340.  
  341.                     }/*if*/
  342.  
  343.                 break;}
  344.  
  345. /* oh well pass back to yacc & let it cope  - if not digit or alpha */
  346.                 default: {
  347.                     if ( isdigit( line[index] ) ) {
  348. /* gobble up digits */
  349.                         index++;
  350.                         while ( isdigit(line[index]) ){
  351.                             index++;
  352.                         }/*while*/
  353.  
  354.                         tok = NUMBER;
  355.                         break;
  356.  
  357.                     } else if ( isalpha( line[index] ) ) {
  358.                         int    i, wlen = 1;
  359.                         index++;
  360. /* gobble up associated chs */
  361.                         while ( isalpha( line[index] )
  362.                             || isdigit( line[index])
  363.                             || line[index] == '.' ){
  364.                             wlen++;
  365.                             index++;
  366.                         }/*while*/
  367.  
  368. /* now check against reserved word list */
  369.                         for ( i=0;
  370.                              rlist[i].word != NULL;
  371.                             i++ ) {
  372.  
  373.                             if ( rlist[i].len
  374.                                 != wlen ) {
  375.                                 continue;
  376.                             }/*if*/
  377.  
  378.                             if ( strncmp(
  379.                               &line[index-wlen],
  380.                               rlist[i].word,
  381.                               wlen ) == 0 ) {
  382.  
  383.                              tok = rlist[i].tok;
  384.                              break;
  385.                             }/*if*/
  386.                         }/*for*/
  387.  
  388. /* not a reserved word */
  389.                         if ( tok < 0 ) {
  390.                             tok = ID;
  391.                         }/*if*/
  392.                         break;
  393.  
  394.                     }/*if*/
  395.  
  396.                     tok = line[index++];
  397.  
  398.                 break;}/*default*/
  399.  
  400.             }/*switch*/
  401.  
  402.         break;}/*Rest*/
  403.  
  404.         case Eof: {
  405. /* do we have some indentation to adjust for ... */
  406.             if ( curind > 0 ) {
  407.                 curind--;
  408.                 tok = END;
  409.             } else {
  410.                 tok = 0;
  411.             }/*if*/
  412.  
  413.  
  414.         break;}/*Eof*/
  415.  
  416.  
  417.     }/*switch*/
  418.  
  419.     }/*while*/
  420.  
  421. /* return whats required after setting yytext etc */
  422.     if ( index > sind ) {
  423.         int    i;
  424.         yylen = index - sind;
  425.  
  426.         for ( i = 0; i < yylen; i++ ) {
  427.             yytext[i] = line[sind+i];
  428.         }/*for*/
  429.  
  430.         yytext[yylen] = '\0';
  431.  
  432.     } else {
  433.         yylen = 0;
  434.         yytext[0] = '\0';
  435.  
  436.     }/*if*/
  437.  
  438. /* debug report */
  439.     if ( ldebug ) {
  440.         fprintf( stderr, "yylex: token %d <%s>\n", tok, yytext );
  441.     }/*if*/
  442.  
  443.     return( tok );
  444.  
  445. }/*yylex*/
  446.  
  447. /*************************************************************************/
  448.  
  449. m_nulline()
  450. /* return true if a null line */
  451. {
  452.  
  453.     int    lindex=index;    /* local index */
  454.  
  455. /* tramp thru spaces */
  456.     while ( line[lindex] == ' ' ) {
  457.         lindex++;
  458.     }/*while*/
  459.  
  460. /* any comment ? */
  461.     if ( line[lindex] == '-' && line[lindex+1] == '-' ) {
  462.         yylineno++;
  463.         return( TRUE );
  464.  
  465. /* or we got to the end of the line */
  466.     } else if ( line[lindex]== '\n' ) {
  467.         yylineno++;
  468.         return( TRUE );
  469.  
  470.     }/*if*/
  471.  
  472.     return( FALSE );
  473.  
  474. }/*m_nulline*/
  475.  
  476. /* end occam2lex.c */
  477.